﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

using NUnit.Framework;
using MCromwell.StaffIntranet.Task.Tasks;

namespace MCromwell.StaffIntranet.Task.Test.integration
{

    [TestFixture]
    public class Task_layer_convention
    {

        [Test]
        public void task_class_methods_should_be_marked_with_wrap_exception_attributes()
        {
            try
            {
                Assembly asm = Assembly.LoadFrom("MCromwell.StaffIntranet.Task.dll");
                var wrapExceptionType = asm.GetType("MCromwell.StaffIntranet.Task.Infrastructure.WrapExceptionWithAttribute");
                Assert.IsNotNull(wrapExceptionType);

                foreach (Type current in asm.GetTypes())
                {
                    
                    if ((current.IsSubclassOf(typeof(AbstractTask))) && (current.FullName.StartsWith("MCromwell.StaffIntranet.Task.Tasks.") && (!current.IsInterface) && (!current.IsAbstract)))
                    {
                        foreach (var method in current.GetMethods())
                        {
                            if ((method.IsPublic) && (method.DeclaringType.Name != "Object"))
                            {
                                if (method.GetCustomAttributes(wrapExceptionType, false).Length <= 0)
                                    Assert.Fail("no wrap exception attribute found on type '{0}', method '{1}'", current.FullName,method.Name);
                            }
                        }
                    }
                }
            }
            catch (ReflectionTypeLoadException rex)
            {
                foreach (var current in rex.LoaderExceptions)
                    Console.WriteLine(current.ToString());
                throw;
            }
            catch (Exception ex)
            {
                Console.Error.Write(ex.Message);
                throw;
            }
            
        }
    }
}
